package com.ruoyi.controller.controller.common;

import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.ServerConfig;

import com.ruoyi.common.utils.DateUtils;
import java.util.UUID;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.region.Region;

/**
 * 通用请求处理
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/common")
public class CommonController
{
    private static final Logger log = LoggerFactory.getLogger(CommonController.class);

    @Autowired
    private ServerConfig serverConfig;

    // COS 配置（使用默认空值，避免未配置时启动报错）
    @Value("${tencent.cos.secretId}")
    private String cosSecretId;
    @Value("${tencent.cos.secretKey}")
    private String cosSecretKey;
    @Value("${tencent.cos.region}")
    private String cosRegion;
    @Value("${tencent.cos.bucket}")
    private String cosBucket;
    // 可选：自定义访问域名前缀，如 CDN 域名或网站反代地址
    @Value("${tencent.cos.baseUrl}")
    private String cosBaseUrl;

    private static final String FILE_DELIMETER = ",";

    /**
     * 通用下载请求
     *
     * @param fileName 文件名称
     * @param delete 是否删除
     */
    @GetMapping("/download")
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
    {
        try
        {
            if (!FileUtils.checkAllowDownload(fileName))
            {
                throw new Exception(StringUtils.format("文件名称({})非法，不允许下载。 ", fileName));
            }
            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
            String filePath = RuoYiConfig.getDownloadPath() + fileName;

            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, realFileName);
            FileUtils.writeBytes(filePath, response.getOutputStream());
            if (delete)
            {
                FileUtils.deleteFile(filePath);
            }
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }

    /**
     * 通用上传请求（单个）改为上传至腾讯云 COS
     */
    @PostMapping("/upload")
    public AjaxResult uploadFile(MultipartFile file) throws Exception
    {
        try
        {
            String key = putCosAndReturnKey(file);
            String url = buildCosUrl(key);
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", url);
            ajax.put("fileName", url);
            ajax.put("newFileName", FileUtils.getName(key));
            ajax.put("originalFilename", file.getOriginalFilename());
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 通用上传请求（多个）改为上传至腾讯云 COS
     */
    @PostMapping("/uploads")
    public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
    {
        try
        {
            List<String> urls = new ArrayList<String>();
            List<String> fileNames = new ArrayList<String>();
            List<String> newFileNames = new ArrayList<String>();
            List<String> originalFilenames = new ArrayList<String>();
            for (MultipartFile f : files)
            {
                String key = putCosAndReturnKey(f);
                String url = buildCosUrl(key);
                urls.add(url);
                fileNames.add(key);
                newFileNames.add(FileUtils.getName(key));
                originalFilenames.add(f.getOriginalFilename());
            }
            AjaxResult ajax = AjaxResult.success();
            ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
            ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
            ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
            ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 本地资源通用下载（保留原行为）
     */
    @GetMapping("/download/resource")
    public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        try
        {
            if (!FileUtils.checkAllowDownload(resource))
            {
                throw new Exception(StringUtils.format("资源文件({})非法，不允许下载。 ", resource));
            }
            // 本地资源路径
            String localPath = RuoYiConfig.getProfile();
            // 数据库资源地址
            String downloadPath = localPath + FileUtils.stripPrefix(resource);
            // 下载名称
            String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, downloadName);
            FileUtils.writeBytes(downloadPath, response.getOutputStream());
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }

    /**
     * 将文件上传到 COS 并返回对象键（key）
     */
    private String putCosAndReturnKey(MultipartFile file) throws Exception {
        if (StringUtils.isEmpty(cosSecretId) || StringUtils.isEmpty(cosSecretKey)
                || StringUtils.isEmpty(cosRegion) || StringUtils.isEmpty(cosBucket)) {
            throw new IllegalStateException("COS配置未完成，请在application.yml中配置 tencent.cos.secretId/secretKey/region/bucket");
        }
        COSCredentials cred = new BasicCOSCredentials(cosSecretId, cosSecretKey);
        ClientConfig clientConfig = new ClientConfig(new Region(cosRegion));
        clientConfig.setHttpProtocol(HttpProtocol.https);
        COSClient cosClient = new COSClient(cred, clientConfig);
        try {
            String original = file.getOriginalFilename();
            String suffix = "";
            if (StringUtils.isNotEmpty(original) && original.lastIndexOf('.') >= 0) {
                suffix = original.substring(original.lastIndexOf('.'));
            }
            String key = "upload/" + DateUtils.datePath() + "/" + UUID.randomUUID().toString().replace("-", "") + suffix;
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(file.getSize());
            metadata.setContentType(file.getContentType());
            PutObjectRequest putObjectRequest = new PutObjectRequest(cosBucket, key, file.getInputStream(), metadata);
            cosClient.putObject(putObjectRequest);
            return key;
        } finally {
            cosClient.shutdown();
        }
    }

    /**
     * 根据对象键构建可访问的URL
     */
    private String buildCosUrl(String key) {
        if (StringUtils.isNotEmpty(cosBaseUrl)) {
            //https://cloud-test.yunxiangfarm.cn/upload/2025/10/17/62db2d7505e5436baf196f3a1b4e542e.jpg
            // 获取key中的最后 /的后面的值
            String fileName = key.substring(key.lastIndexOf("/") + 1);

            // 生成一个16位的uuid
            String uuid = UUID.randomUUID().toString().replace("-", "");
            return cosBaseUrl.endsWith("/") ? cosBaseUrl + key : (cosBaseUrl + "/" + key);
        }
        return String.format("https://%s.cos.%s.myqcloud.com/%s", cosBucket, cosRegion, key);
    }
}
